function vlink (context)
{
	this.vlink_id;
	this.opp_ipv6;
	this.loc_ipv4;
	this.opp_ipv4;
	this.link_state;
	this.go_hops;
	this.come_hops;
	this.rtt;
	this.send_interval;
}

function router (context)  /*router class*/
{
	this.arc_cnt_pts = new Array();// = [x, y];
	this.radius = 15;
	this.ipv6_addr = "";
	this.port;
	this.vlink_num = 1;
	this.link_state = false;
	this.neigh_vr = new Array();
	this.vlink_arr = new Array();
	this.get_neigh_vr = function ()
	{
		for (var i in vlink_arr)
		{
			neigh_vr[i] = vlink_arr[i].opp_ipv6;
		}
	}
	this.shift = false;
	
	this.draw = function () 
	{
		if (this.link_state == true)
		{
			context.fillStyle = "rgba(0, 128, 0, 1)";
		}
		else 
		{
			if (this.shift == false)
			{
				context.fillStyle = "rgba(255, 0, 0, 1)";
			}
			else
			{
				context.fillStyle = "rgba(128, 0, 0, 1)";
			}
		}
		context.beginPath();
		context.arc(this.arc_cnt_pts[0], this.arc_cnt_pts[1], this.radius,0,Math.PI*2,true);
		/*context.lineWidth = 10;*/
		context.shadowOffsetX = 2;
		context.shadowOffsetY = 2;
		context.shadowBlur = 2;
		context.shadowColor = "rgba(0, 0, 0, 0.5)";
		context.stroke();
		context.fill();
		context.closePath();
	
		context.beginPath();
		context.shadowOffsetX = 0;
		context.shadowOffsetY = 0;
		context.shadowBlur = 0;
		context.font = "italic 10px sans-serif";
		context.fillText  (this.ipv6_addr, this.arc_cnt_pts[0], this.arc_cnt_pts[1]-15);
		context.stroke();
		context.fill();
		context.closePath();
	}
}


function topology_drawing ()	/*topology_drawing class*/
{
	this.canvas = null;
	this.context = null;
	this.draw_space;
	this.draw_radius;
	this.init_canvas = function (canvasid)
	{
		try
		{
			this.canvas = document.getElementById(canvasid);
		}
		catch (e)
		{
			alert(e.message);
		}
		if (!this.canvas)
		{
			alert("Error: I cannot find the canvas element!");
			return;
		}
		if (!this.canvas.getContext)
		{
			alert("Error: no canvas.getContext!");
			return;
		}
		this.draw_space = (this.canvas.width<this.canvas.height)?this.canvas.width:this.canvas.height;
		this.draw_radius = Math.floor(this.draw_space/2) - 30;
		//alert(this.draw_radius);
		try
		{
			this.context = this.canvas.getContext("2d");
		}
		catch (e)
		{
			alert(e.message);
		}
		if (!this.context)
		{
			alert("Error: failed to getContext!");
			return;
		}
		//alert("init suc");
	}
	
	this.xml_src = "nihao";
	//this.xotree;
	this.xotree = new XML.ObjTree();
	this.tree;
	this.vr_amount;
	this.routers_arr = new Array();

	this.create_router = function ()
	{
		//this.xotree = new XML.ObjTree();
		//alert("xml_src\n"+this.xml_src);
		this.tree = this.xotree.parseXML(this.xml_src);
		this.vr_amount = 0;
		//alert(this.tree.topology.vr[0].vraddr);
		for (var i in this.tree.topology.vr)
		{
			//alert(i +" = "+ this.tree.topology.vr[i]);
			this.routers_arr[this.vr_amount] = new router(this.context);
			this.routers_arr[this.vr_amount].ipv6_addr = this.tree.topology.vr[i].vraddr;
			this.routers_arr[this.vr_amount].port = this.tree.topology.vr[i].port;
			this.routers_arr[this.vr_amount].vlink_num = this.tree.topology.vr[i].numofvlink;
			this.routers_arr[this.vr_amount].link_state = this.tree.topology.vr[i].linkstate>0?true:false;

			var counter = 0;
			for (var j in this.tree.topology.vr[i])
			{
				if ( typeof(this.tree.topology.vr[i][j]) == "object" )
				{
					this.routers_arr[this.vr_amount].vlink_arr[counter] = new vlink(this.context);
					this.routers_arr[this.vr_amount].vlink_arr[counter].vlink_id = this.tree.topology.vr[i][j].vlinkid;
					this.routers_arr[this.vr_amount].vlink_arr[counter].opp_ipv6 = this.tree.topology.vr[i][j].oppipv6;
					this.routers_arr[this.vr_amount].vlink_arr[counter].loc_ipv4 = this.tree.topology.vr[i][j].locipv4;
					this.routers_arr[this.vr_amount].vlink_arr[counter].opp_ipv4 = this.tree.topology.vr[i][j].oppipv4;
					this.routers_arr[this.vr_amount].vlink_arr[counter].link_state = this.tree.topology.vr[i][j].linkstate;
					this.routers_arr[this.vr_amount].vlink_arr[counter].go_hops = this.tree.topology.vr[i][j].gohops;
					this.routers_arr[this.vr_amount].vlink_arr[counter].come_hops = this.tree.topology.vr[i][j].comehops;
					this.routers_arr[this.vr_amount].vlink_arr[counter].rtt = this.tree.topology.vr[i][j].rtt;
					this.routers_arr[this.vr_amount].vlink_arr[counter].send_interval = this.tree.topology.vr[i][j].sendinterval;
					counter++;
				}
			}
			this.vr_amount++;
		}
		//alert(this.routers_arr[0].ipv6_addr);
		//alert(this.routers_arr[0].vlink_arr[0].opp_ipv6);
	}
	this.conn_pts_pair = new Array();
	this.find_path = function ()
	{
		//var traveled_nodes = new Array();
		//var nodes_counter = 0;
		var conn_pts_counter = 0;
		for (var i in this.routers_arr)
		{
			//traveled_nodes[nodes_counter] = this.routers_arr[i].ipv6_addr;
			for (var j in this.routers_arr[i].vlink_arr)
			{
				this.conn_pts_pair[conn_pts_counter] = new Array();
				this.conn_pts_pair[conn_pts_counter][0] = this.routers_arr[i].arc_cnt_pts;
				for (var k in this.routers_arr)
				{
					if (this.routers_arr[i].vlink_arr[j].opp_ipv6 == this.routers_arr[k].ipv6_addr)
					{
						this.conn_pts_pair[conn_pts_counter][1] = this.routers_arr[k].arc_cnt_pts;
					}
				}
				conn_pts_counter++;
			}
			//nodes_counter++;
		}
		//alert(conn_pts_counter);
		//alert(this.conn_pts_pair.length);
		//alert(nodes_counter);
	}
	this.draw_vlinks = function ()
	{
		this.context.fillStyle = "rgba(0, 0, 0, 1)";
		this.context.globalCompositeOperation = "destination-over";
		this.context.beginPath();
		this.context.shadowOffsetX = 2;
		this.context.shadowOffsetY = 2;
		this.context.shadowBlur = 2;
		this.context.shadowColor = "rgba(0, 0, 0, 0.5)";
		if (this.conn_pts_pair.length > 0)
		{
			for (var i in this.conn_pts_pair)
			{
				this.context.moveTo(this.conn_pts_pair[i][0][0], this.conn_pts_pair[i][0][1]);
				this.context.lineTo(this.conn_pts_pair[i][1][0], this.conn_pts_pair[i][1][1]);
			}
		}
		else
		{
			alert("no elements in array conn_pts_pair.");
		}
		this.context.stroke();
		this.context.closePath();
	}
	this.locate = function ()
	{
		var centre_angle = (Math.PI*2)/this.vr_amount;
		for (var i = 0; i < this.vr_amount; i++)
		{
			var x = Math.round(this.draw_radius*Math.cos(Math.PI/2+i*centre_angle));
			var y = Math.round(this.draw_radius*Math.sin(Math.PI/2+i*centre_angle));
			x += this.draw_radius + 30;
			y += this.draw_radius + 30;

			this.routers_arr[i].arc_cnt_pts[0] = x;
			this.routers_arr[i].arc_cnt_pts[1] = y;
		}
	}

	this.draw_routers = function ()
	{
		this.locate();
		for (var i in this.routers_arr)
		{                    
			this.routers_arr[i].draw();
		}     
	}

}


	/*
	   this.change_color = function ()
	   {
	//if (this.status == false)
	{
	if (this.shift == false)
	{
	context.save();
	this.draw();
	this.shift = true;
	context.restore();                            
	}
	else
	{
	context.save();
	this.draw();
	this.shift = false;
	context.restore();                            
	}
	}
	}
	*/


/*
	   this.color_shift = function () 
	   {
	   for (var i in this.routers_arr)
	   {
	   if (this.routers_arr[i].status == false)
	   {
	   this.routers_arr[i].change_color();
	   }
	   }
	   }
	   */
